<?php

class User extends BaseUser
{
    public static $rt_info_fields = array(
        'email', 'locale', 'first_name', 'last_name', 'name'
    );
    // FQL fields, used for RT updates
    public static $info_fields;
    public static function _initStatic()
    {
        self::$info_fields = array_merge(self::$rt_info_fields, array('third_party_id'));
    }

    private $user_info = null;

    /**
     * Returns a valid Symfony culture from Facebook's locale
     */
    public function getCulture()
    {
        return vtnsCultureInfo::getCultureFromLocale($this->locale);
    }


    // Warning: $amount is in cents
    public function refund($page_id, $email, $amount)
    {
        $sponsoring_refund = new SponsoringReturn();
        $sponsoring_refund->godfather_uid = $this->uid;
        $sponsoring_refund->godchild_uid = null;
        $sponsoring_refund->page_id = $page_id;
        sfContext::getInstance()->getLogger()->info('{User} Email: '.$email);
        sfContext::getInstance()->getLogger()->info('{User} Amount: '.$amount);
        sfContext::getInstance()->getLogger()->info('{User} $this->uid.\'P\'.$page_id: '.$this->uid.'P'.$page_id);

        $sponsoring_refund->action = 'refund';
        $sponsoring_refund->action_amount = 0;
        $sponsoring_refund->return_amount = 0 - $amount;
        $sponsoring_refund->save();

        $params = array(
            'USER'                   => sfConfig::get('sf_paypal_user_id'),
            'PWD'                    => sfConfig::get('sf_paypal_pwd'),
            'SIGNATURE'              => sfConfig::get('sf_paypal_signature'),
            'VERSION'                => '51.0',
            'METHOD'                 => 'MassPay',
            'RECEIVERTYPE'           => 'EmailAddress',
            'L_EMAIL0'               => $email,
            'L_AMT0'                 => sprintf('%.2f', $amount / 100),
            'L_NOTE0'                => '1234567890',
            'CURRENCYCODE'           => 'USD',
            'L_UNIQUEID0'            => $sponsoring_refund->return_id,
            );


        $web_client = new WebClient();
        $body = $web_client->post('https://api-3t.paypal.com/nvp', $params);
        sfContext::getInstance()->getLogger()->info('{refundAction} Paypal Response: '.var_export($body, true));

    }


    /**
     * Fetches user info from Facebook's API
     * This function calls the API only once and caches the result.
     */
    public function updateInfo()
    {
        // Call the Facebook API only once
        if ($this->user_info !== null)
            return;
        $this->user_info = false;

        try {
            $users_info = App::call_api(array(
                    'method' => 'users.getInfo',
                    'uids'   => $this->uid,
                    'fields' => implode(',', self::$info_fields),
                    ));
            if (!isset($users_info[0]))
                throw new Exception("Empty result");

            $this->user_info = $users_info[0];
            $this->doUpdateInfo($this->user_info);
        } catch (Exception $e) {
            sfContext::getInstance()->getLogger()->err("{User} updateInfo: ".$e->getMessage());
        }
    }


    private function doUpdateInfo($info)
    {
        foreach (self::$info_fields as $field)
            if (!empty($info[$field]))
                $this->$field = $info[$field];

        $this->rt_valid = true;
        $this->rt_updated_at = date(DATE_ISO8601);
    }


    /**
     * This is used to update the counters next to the app icon on
     * a candidate's facebook home page with the number of jobs matching his alerts
     * Calls to FacebookAPI are made by chunks of 50 users.
     *
     * @return array with the request status for each id.
     */
    public static function updateAllCountersSince($last_run)
    {
        $q = Doctrine::getTable('User')->createQuery('u')
                         ->leftJoin('u.Alerts a')
                         ->addWhere('a.is_active = 1')
                         ->addWhere('a.updated_at > ?', $last_run)
                         ->groupBy('u.uid');
        $users = $q->execute();
        $idsList = array();
        if (!$users)
            return null;
        foreach ($users as $fb_user) {
            $idsList[$fb_user->uid] = 0;
            foreach ($fb_user->Alerts as $alert)
                $idsList[$fb_user->uid] += $alert->new_jobs_count;
        }

        $idsList = array_chunk($idsList,40,true);

        $response = array();
        foreach ($idsList as $ids) {
            vtnsLog::info('{FacebookApi} dashboard.multiSetCount, ids: '.var_export($ids, true));
            $rep = App::call_api(array(
                    'method' => 'dashboard.multiSetCount',
                    'ids'    => $ids,
                    ));
            if (!is_array($rep))
                return array('FacebookApi error, app_counters not correctly updated this time!' => $rep);
            $response = $response + $rep;
        }
        return $response;
    }


    public function resetAppCounter()
    {
        sfContext::getInstance()->getLogger()->info('{FacebookApi} dashboard.setCount, id: '.$this->uid);
        $response = App::call_api(array(
                'method' => 'dashboard.setCount',
                'uid'    => $this->uid,
                'count'  => 0,
                ));
        foreach ($this->Alerts as $alert) {
            $alert->new_jobs_count = 0;
            $alert->save();
        }
        return $response;
    }


    private static function generatePublicSafeToken($uid)
    {
        $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
        $n = 36;
        $token='';
        $quotient = $uid;
        while($quotient > 0)
        {
            $rest = (int) $quotient % $n;
            $quotient = (int) $quotient / $n;
            $char = $characters[$rest];
            $token .= $char;
        }
        return $token;
    }


    public function getAlertsQuery()
    {
        return Doctrine_Query::create()
            ->from('CandidateAlert c')
            ->addWhere('c.is_active = 1')
            ->addwhere('c.uid = ?', $this->uid);
    }


    public function isCustomer()
    {
        return !$this->isAdmin();
    }


    /**
     * Test if an identical alert already exists for this user.
     */
    public function hasAlert(CandidateAlert $newAlert)
    {
        foreach ($this->Alerts as $oldAlert)
            if ($oldAlert->is_active === true && $newAlert->equals($oldAlert))
                return true;

        return false;
    }


    /**
     * Returns true if we would like to get more info about the user
     */
    public function isMissingField()
    {
        foreach (self::$info_fields as $field)
            if (!$this->$field)
                return true;
        return false;
    }


    public function isAdmin()
    {
        $page_id = sfContext::getInstance()->getUser()->getPageId();
        $q = Doctrine_Query::create()
            ->from('PageAdmin')
            ->addWhere('page_id = ?', $page_id)
            ->addwhere('uid = ?', $this->uid)
            ->addWhere('is_admin = ?', 1);
        return count($q->execute()) > 0;
    }
}

User::_initStatic();

?>
